//
//  AudioViewController.m
//  Foundation
//
//  Created by 新庭 on 2020/8/1.
//  Copyright © 2020 iyinyue. All rights reserved.
//

#import "AudioViewController.h"
#import <Masonry/Masonry.h>
#import "AudioTrackCell.h"
#import "FAudioAnalyzer.h"
#import "AudioView.h"
#import "OouraFFT.h"

@import AVFoundation;

@interface AudioViewController () <UITableViewDelegate, UITableViewDataSource>

@property (nonatomic, strong) AudioView *audioView;
@property (nonatomic, strong) UITableView *tableView;
@property (nonatomic, strong) NSArray<NSString *> *trackPathes;

@property (nonatomic, strong) AVAudioEngine *engine;
@property (nonatomic, strong) AVAudioPlayerNode *player;
@property (nonatomic, strong) FAudioAnalyzer *analyzer;
@property (nonatomic, strong) OouraFFT *fft;

@end

@implementation AudioViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.view.backgroundColor = [UIColor whiteColor];
    [self prepareSubviews];
    
    self.trackPathes = [[NSBundle mainBundle] pathsForResourcesOfType:@"mp3" inDirectory:nil];
    self.engine = [[AVAudioEngine alloc] init];
    self.player = [[AVAudioPlayerNode alloc] init];
    
    [self.engine attachNode:self.player];
    [self.engine connect:self.player to:self.engine.mainMixerNode format:nil];
    [self.engine prepare];
    [self.engine startAndReturnError:nil];
    [self initBuffer:2048];
    
    self.analyzer = [[FAudioAnalyzer alloc] init];
    self.fft = [[OouraFFT alloc] initForSignalsOfLength:2048 andNumWindows:80];
    
    
    [self refresh];
}

- (void)refresh {
    [self.tableView reloadData];
}

- (void)prepareSubviews {
    self.audioView = [[AudioView alloc] init];
    [self.view addSubview:self.audioView];
    [self.audioView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.left.right.mas_offset(0);
        make.height.mas_equalTo(300);
    }];
    
    self.tableView = [[UITableView alloc] init];
    [self.tableView registerClass:AudioTrackCell.class forCellReuseIdentifier:NSStringFromClass(AudioTrackCell.class)];
    self.tableView.dataSource = self;
    self.tableView.delegate = self;
    [self.view addSubview:self.tableView];
    [self.tableView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.mas_equalTo(self.audioView.mas_bottom);
        make.left.right.bottom.mas_offset(0);
    }];
}

- (void)viewDidDisappear:(BOOL)animated {
    [self.player stop];
    [self.engine stop];
    [super viewDidDisappear:animated];
}

#pragma mark - Table View
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return self.trackPathes.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    AudioTrackCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass(AudioTrackCell.class)];
    cell.textLabel.text = [[self.trackPathes[indexPath.row] lastPathComponent] stringByDeletingPathExtension];
    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    NSString *path = self.trackPathes[indexPath.row];
    
    [self.player stop];
    AVAudioFile *file = [[AVAudioFile alloc] initForReading:[NSURL fileURLWithPath:path] error:nil];
    [self.player scheduleFile:file atTime:nil completionHandler:nil];
    [self.player play];
}

#pragma mark - Private
- (void)initBuffer:(NSInteger)size {
    [self.engine.mainMixerNode removeTapOnBus:0];
    [self.engine.mainMixerNode installTapOnBus:0 bufferSize:(AVAudioFrameCount)size format:nil block:^(AVAudioPCMBuffer * _Nonnull buffer, AVAudioTime * _Nonnull when) {
        if (!self.player.isPlaying) {
            return;
        }
        
        buffer.frameLength = (AVAudioFrameCount)size;
        self.fft.inputData = buffer;
//        [self handleBuffer:[self.analyzer analyse:buffer]];
    }];
}

- (void)handleBuffer:(NSArray<NSArray<NSNumber *> *> *)buffer {
    dispatch_async(dispatch_get_main_queue(), ^{
        self.audioView.spectra = buffer;
    });
}

@end
